<?php
namespace Twoir\Service\Info;

use Config;
use Exception;
use Twoir\Service\BaseInfo;
use Twoir\System\Support\ParamTrait;

/**
 * 信息详情
 *
 * cighsen02 3651872575
 *
 * Create at: 2024.05.05
 * Update at: 2025.05.10
*/
class Detail extends BaseInfo
{
    use ParamTrait;

	const ALLOW = ['classid', 'id', 'pathid', 'tablename', 'filename'];
	// 当次拉取缓存列表
	protected $info;
	/**
	 * 获取详情
	 *
	 * @param array $add
	 * @return array
     *
     * @throws Exception
	*/
	public function get(array $add): array
	{
		// 过滤无关参数
		$add = $this->paramFilter($add);

		if (empty($add)) throw new Exception("参数错误!", 9200);

		if (!isset($add['classid']) || empty($add['classid'] = (int)$add['classid'])) {

		    if (!isset($add['tablename']) || empty($add['tablename'])) {

		        throw new Exception("classid或tablename必要参数", 9200);
		    }
		}

		if (!isset($add['id']) || empty($add['id'] = (int)$add['id'])) throw new Exception("id必要参数", 9200);
        // 键名采用小驼峰命名
        $modelName  = camel_case($this->modelName());
		// 定义获取的字段
		$field      = Config::twoir('api.' . $modelName . '.page') ?? ['*'];
		$result     = $this->getOne(['id' => $add['id']], $field);

		return $this->format($result);
	}

	/**
	 * 点击统计
	 *
	 * @param array $add
	 * @return array
     *
     * @throws Exception
	 */
	public function onClick(array $add): array
	{
		global $public_r, $emod_pubr, $class_r;

		// 过滤无关参数
		$add = $this->paramFilter($add);

		if (empty($add)) throw new Exception('参数错误!', 9200);

		if (!isset($add['classid']) || empty($add['classid'] = (int)$add['classid'])) {

		    if (!isset($add['tablename']) || empty($add['tablename'])) {

		        throw new Exception('classid或tablename必要参数', 9200);
		    }
		}

		if (!isset($add['id']) || empty($add['id'] = (int)$add['id'])) throw new Exception("id必要参数", 9200);

		if (!$this->checkCookie('ecookieinforecord', $add['classid'] . '-' . $add['id'])) return [];
		// 获取字段，表没有时自动过虑，多写不影响
		if (empty($r = $this->getOne(['id' => $add['id']], ['id','eotime','eoday']))) throw new Exception('信息不存在', 9200);

		if(empty($this->tablename) || InfoIsInTable(strtolower($this->tablename))) return [];

		// onclicktype: 0实时统计,1文本缓存,2不统计
		if(0 === (int)$public_r['onclicktype'])	{

			// 浏览年月日统计 前缀eo为浏览 ed为下载
			$tid 	= $class_r[$add['classid']]['tid'];
			$update = ['onclick' => 'onclick + 1'];
			if(str_contains($emod_pubr['tbidseo'], ',' . $tid . ',')) {

				if (isset($r['eotime'])) {
					$nowtime 	= time();
					$date		= date('Y-m-d', $nowtime);
					$year		= date('Y', $nowtime);
					$month		= date('n', $nowtime);
					$week		= date('W', $nowtime);
					$day		= date('j', $nowtime);
					$halfyear	= $month > 6 ? 1 : 0;
					$quarter 	= $this->quarter($month);

					$tdate		= date('Y-m-d', $r['eotime']);
					$tyear		= date('Y', $r['eotime']);
					$tmonth		= date('n', $r['eotime']);
					$tweek		= date('W', $r['eotime']);
					$tday		= date('j', $r['eotime']);
					$thalfyear	= $tmonth > 6 ? 1 : 0;
					$tquarter 	= $this->quarter($tmonth);

					$update['eotime'] = $nowtime;
					// 年
					$update['eoyear'] = $tyear !== $year ? 0 : 'eoyear + 1';
					// 半年
					$update['eohalfyear'] = $thalfyear !== $halfyear ? 0 : 'eohalfyear + 1';
					// 季度
					$update['eoquarter'] = $tquarter !== $quarter ? 0 : 'eoquarter + 1';
					// 月
					$update['eomonth'] = $tmonth !== $month ? 0 : 'eomonth + 1';
					// 周
					$update['eoweek'] = $tyear !== $year || $tweek !== $week ? 0 : 'eoweek + 1';
					// 天
					$update['eoday'] = $tyear . '-' . $tmonth.'-'.$tday !== $year . '-' . $month . '-' . $day ? 0 : 'eoday + 1';
					// 昨天
					if($tdate !== $date) {

						$update['eoyesterday'] = date('Y-m-d',$nowtime - 24 * 3600) == $tdate ? $r['eoday'] : 0;
					}
				}
			}

			$this->update(['id' => $add['id']], $update);
		}
		elseif (1 === (int)$public_r['onclicktype']) {

			$tid = $class_r[$add['classid']]['tid'];
			$filename = ECMS_PATH . 'c' . DIRECTORY_SEPARATOR . 'ecachepub' . DIRECTORY_SEPARATOR . 'efilecache' . DIRECTORY_SEPARATOR . 'econclick' . DIRECTORY_SEPARATOR . 'ocinfo' . $tid . '.log';
			// 以下功能未实现
			$this->addUpdate($add['id'], $filename);
			$this->doUpdate('id', 'onclick', $filename);
		}

		return [];
	}

	/**
	 * 加入点击缓存
	 *
	 * @param int $id
	 * @param string $filename
	 * @return void
	*/
	private function addUpdate(int $id, string $filename): void
	{
		if(@$fp = fopen($filename, 'ab')){

			fwrite($fp, "$id\n");
			fclose($fp);
		}
	}

	/**
	 * 更新点击缓存
	 *
	 * @param int $id
	 * @param string $filename
	 * @return void
	*/
	private function doUpdate(string $idf, string $onclickf, string $filename): string
	{
		global $public_r;

		if(file_exists($filename) && (filesize($filename) >= $public_r['onclickfilesize'] * 1024 || time() - filectime($filename) >= $public_r['onclickfiletime'] * 60)){
			$lr = $ocr = [];
			if($lr = file($filename)){

				if(!unlink($filename)){

					if($fp = fopen($filename, 'wb')){

						fwrite($fp, '');
						fclose($fp);
					}
				}
				$lr = array_count_values($lr);
				foreach($lr as $id => $oc){

					array_push($ocr[$oc], intval($id));
				}

				foreach($ocr as $oc => $ids){

					if (count($ids) > 1) {

						$this->update([$idf . ' in' => $ids], [$onclickf => $onclickf . ' + ' . intval($oc)]);
					}
					else {

						$this->update([$idf => $ids], [$onclickf => $onclickf . ' + ' . intval($oc)]);
					}
				}
			}
		}

		return '';
	}

	/**
	 * 季度
	 *
	 * @param int $manth
	 * @return int
	 */
	private function quarter(int $month): int
	{
		return match (true) {
			$month >= 4 && $month <= 6 		=> 2,
			$month >= 7 && $month <= 9 		=> 3,
			$month >= 10 && $month <= 12 	=> 4,
			default => 1,
		};
	}

	/**
	 * 存在cookie
	 *
	 * @param string $cookieName
	 * @param string $value
	 * @return bool
	 */
	private function checkCookie(string $cookieName, string $value): bool
	{
		$doupdate = true;
		$onclickrecord = getcvar($cookieName);
		if(str_contains($onclickrecord, ',' . $value . ',')) {
			$doupdate = false;
		}
		else {

			$newval = empty($onclickrecord) ? ',' . $value .',' : $onclickrecord . $value . ',';
			esetcookie($cookieName, $newval);
		}

		if(empty($_COOKIE))	$doupdate = false;

		return $doupdate;
	}
}
